package com.lizhi.dingdong.apk.util

import java.io.PrintStream
import java.nio.charset.StandardCharsets
import java.util.*
import kotlin.collections.forEach
import kotlin.collections.toList

/**
 * 固定容量的先进先出 (FIFO) 队列。
 * 当容量已满时，新的元素插入将自动删除最老的元素（队首）。
 * * @param T 队列中存储的元素类型
 * @param capacity 队列的最大容量
 */
class FixedSizeQueue<T>(val capacity: Int) {

    // 使用 ArrayDeque 作为底层数据结构，因为它支持在 O(1) 时间复杂度内从两端添加和删除元素。
    private val queue: ArrayDeque<T> = ArrayDeque(capacity)

    /**
     * 获取队列中当前的元素数量。
     */
    val size: Int
        get() = queue.size

    /**
     * 将元素添加到队列的末尾。
     * 如果队列已满，则删除队首（最老的）元素。
     * * @param element 要添加的元素
     */
    fun add(element: T) {
        // 1. 检查容量是否已满
        if (queue.size >= capacity) {
            // 容量已满，删除最老的元素（队首）
            val removed = queue.removeFirst()
            println("--- 缓存已满，移除最老元素: $removed ---")
        }

        // 2. 将新元素添加到队尾
        queue.addLast(element)
    }


    /**
     * 批量添加元素到队列的末尾。
     * 如果队列已满，将根据 FIFO 规则删除最老的元素。
     * @param elements 要添加的元素集合
     */
    fun addAll(elements: Collection<T>) {
        elements.forEach { element ->
            // 重复利用已有的 add 函数，确保每个元素都能触发容量检查和淘汰逻辑
            add(element)
        }
    }

    /**
     * 返回队列中所有元素的列表。
     */
    fun toList(): List<T> = queue.toList()

    /**
     * 清空队列。
     */
    fun clear() = queue.clear()
}

/**
 * 演示 FixedSizeQueue 的使用。
 */
fun main() {
    // 修复中文乱码问题：强制将 System.out 的输出编码设置为 UTF-8
    try {
        System.setOut(PrintStream(System.out, true, StandardCharsets.UTF_8.name()))
    } catch (e: Exception) {
        // 忽略设置失败（例如在受限环境中）
    }

    // 创建一个最大容量为 3 的缓存
    val cache = FixedSizeQueue<String>(capacity = 3)

    println("--- 步骤 1: 首次添加数据 (容量未满) ---")
    cache.add("A: Login Event")
    cache.add("B: Cart Update")
    println("当前缓存: ${cache.toList()}") // [A, B]

    println("\n--- 步骤 2: 添加第 3 个数据 (达到容量限制) ---")
    cache.add("C: Checkout Success")
    println("当前缓存: ${cache.toList()}") // [A, B, C]

    println("\n--- 步骤 3: 添加第 4 个数据 (触发删除，'A' 被删除) ---")
    // A 是最老的，将被删除
    cache.add("D: Profile View")
    println("当前缓存: ${cache.toList()}") // [B, C, D] (A 被移除)

    println("\n--- 步骤 4: 添加第 5 个数据 (触发删除，'B' 被删除) ---")
    // B 是最老的，将被删除
    cache.add("E: Image Load")
    println("当前缓存: ${cache.toList()}") // [C, D, E] (B 被移除)
}